<?php
// 函数库
//声明编码
header("Content-Type:text/html;charset=utf-8");

/**
 * 数据库查询函数
 */

// 单条查询
if (!function_exists('find')) {
  function find($sql = null)
  {
    //引入全局变量
    global $conn;
    // var_dump($sql);
    // exit;
    $res = mysqli_query($conn, $sql);
    if ($res && mysqli_num_rows($res) > 0) {
      //返回数据
      return mysqli_fetch_assoc($res);
    } else return mysqli_error($conn);
  }
}

// 多条查询
if (!function_exists('all')) {
  function all($sql = null)
  {
    //引入全局变量
    global $conn;
    $res = mysqli_query($conn, $sql);
    if ($res && mysqli_num_rows($res) > 0) {
      // 多条数据就是要循环
      $list = [];
      while ($data = mysqli_fetch_assoc($res)) {
        $list[] = $data;
      }
      //返回数据
      return $list;
    } else return mysqli_error($conn);
  }
}

// 插入函数
if (!function_exists('add')) {
  function add($table, $data)
  {
    // INSERT INTO 表名(`字段1`,`字段2`,`字段3`)VALUES('值1','值2','值3')
    global $conn;
    global $pre_;
    //给表名拼接上表前缀
    $table = $pre_ . $table;
    //将数组里面的索引全部提取出来变成一个新数组
    $keys = array_keys($data);
    //数组变成字符串
    $fields = "`" . implode("`,`", $keys) . "`";
    $values = "'" . implode("','", $data) . "'";
    $sql = "INSERT INTO $table($fields)VALUES($values)";

    //执行语句
    $res = mysqli_query($conn, $sql);
    if ($res) {
      return [
        'code' => 1,
        'msg' => '添加数据成功',
        'data' => mysqli_insert_id($conn)
      ];
    } else return [
      'code' => 0,
      'msg' => '添加数据失败',
      'data' => mysqli_error($conn)
    ];
  }
}

// 更新
if (!function_exists('update')) {
  /**
   * @param string $table 表名
   * @param array $data 更新的数据
   * @param string $where 更新条件
   */
  function update($table, $data, $where = 1)
  {
    //UPDATE 表名 SET `字段1` = '值1', `字段2` = '值2' WHERE 条件
    global $conn;
    global $pre_;
    //拼接表名
    $table = $pre_ . $table;
    //直接组装
    $str = "";
    foreach ($data as $key => $item) {
      $str .= "`$key` = '$item',";
    }
    $str = rtrim($str, ",");
    //组装sql语句
    $sql = "UPDATE $table SET $str WHERE $where";
    //执行sql
    $res = mysqli_query($conn, $sql);
    if ($res) {
      return true;
    } else return mysqli_error($conn);
  }
}

// 删除
if (!function_exists('del')) {
  /**
   * @param string $table 表名
   * @param string $where 删除条件
   */
  function del($table, $where = 1)
  {
    //DELETE FROM 表名 WHERE where
    global $conn;
    global $pre_;
    $table = $pre_ . $table;
    $sql = "DELETE FROM $table WHERE $where";
    //执行sql
    $res = mysqli_query($conn, $sql);
    // pre($sql);
    // exit;
    if ($res) {
      return true;
    } else return mysqli_error($conn);
  }
}

if (!function_exists('pre')) {
  /**
   * 格式化输出变量的结构化信息（用于调试）
   * 
   * 该函数将变量内容包裹在HTML <pre>标签中输出，增强可读性。
   * 适用于调试时查看变量类型和数据结构。
   *
   * @param mixed $data 需要调试输出的变量/数据，支持所有数据类型
   * @return void 该函数没有返回值
   */
  function pre($data)
  {
    echo '<pre>';
    var_dump($data);
    echo '</pre>';
  }
}

if (!function_exists('notice')) {
  /**
   * 提示信息
   */
  function notice($msg, $url = null)
  {
    if ($url) {
      echo "<script>alert('$msg');location.href = '$url'</script>";
      exit;
    } else {
      echo "<script>alert('$msg');history.back();</script>";
      exit;
    }
  }
}

// 生成随机字符
if (!function_exists('build_randstr')) {
  /**
   * 获得随机字符串
   * @param $len             需要的长度,默认为10
   * @param $special        是否需要特殊符号,默认不需要
   * @return string       返回随机字符串
   */
  function build_randstr($len = 10, $special = false)
  {
    // 定义字符
    $chars = array(
      "a",
      "b",
      "c",
      "d",
      "e",
      "f",
      "g",
      "h",
      "i",
      "j",
      "k",
      "l",
      "m",
      "n",
      "o",
      "p",
      "q",
      "r",
      "s",
      "t",
      "u",
      "v",
      "w",
      "x",
      "y",
      "z",
      "A",
      "B",
      "C",
      "D",
      "E",
      "F",
      "G",
      "H",
      "I",
      "J",
      "K",
      "L",
      "M",
      "N",
      "O",
      "P",
      "Q",
      "R",
      "S",
      "T",
      "U",
      "V",
      "W",
      "X",
      "Y",
      "Z",
      "0",
      "1",
      "2",
      "3",
      "4",
      "5",
      "6",
      "7",
      "8",
      "9"
    );
    // 特殊字符
    if ($special) {
      $chars = array_merge($chars, array(
        "!",
        "@",
        "#",
        "$",
        "?",
        "|",
        "{",
        "/",
        ":",
        ";",
        "%",
        "^",
        "&",
        "*",
        "(",
        ")",
        "-",
        "_",
        "[",
        "]",
        "}",
        "<",
        ">",
        "~",
        "+",
        "=",
        ",",
        "."
      ));
    }
    // 获取字符的长度
    $charsLen = count($chars) - 1;
    // 打乱数组顺序
    shuffle($chars);
    // 存放拼接的字符串
    $str = '';
    for ($i = 0; $i < $len; $i++) {
      // 随机取出一位
      $str .= $chars[mt_rand(0, $charsLen)];
    }
    // 拼接好的字符串
    return $str;
  }
}

if (!function_exists('build_upload')) {
  /**
   * 单图上传
   * @param string $name 图片名
   * @param array $type 上传类型
   * @param string $path 指定的保存路径
   * @param int|string $size 限制传入的图片大小
   * @return array $result 结果集
   */
  function build_upload($name, $type = ['jpg', 'jpeg', 'png', 'gif'], $path  = 'uploads', $size = 1048576)
  {
    // 定义结果集
    $result = [
      'code' => 0, // 1 成功 0 失败
      'msg' => '未知信息', // 提示信息
      'data' => null, // 返回图片保存的路径
    ];
    $date = date('Ymd');
    // 组装保存地址
    $path = $_SERVER['DOCUMENT_ROOT'] . '/' . $path . '/' . $date;
    if (!is_dir($path)) {
      mkdir($path, 0755, true); // true允许递归建立文件夹
    }
    // 获取文件相关信息
    $file = $_FILES[$name] ?? '';
    // 获取上传状态码
    $ErrorCode = $file['error'] ?? 4;
    // 判断当前上传状态码属于哪个错误
    switch ($ErrorCode) {
      case 1:
        $result['msg'] = '上传图片大小不能超过upload_max_filesize设置的值';
        return $result;
      case 2:
        $result['msg'] = '上传图片大小不能超过MAX_FILE_SIZE设置的值';
        return $result;
      case 3:
        $result['msg'] = '上传图片不完整';
        return $result;
      case 4:
        $result['msg'] = '没有上传图片';
        return $result;
      default:
    }
    // 判断图片格式是否符合
    $ext = pathinfo($file['name'], PATHINFO_EXTENSION);
    if (!in_array($ext, $type)) {
      $result['msg'] = '上传图片格式错误';
      return $result;
    }
    // 判断图片大小是否超出指定值
    $FileSize = $file['size'] ?? 0;
    if ($FileSize > $size) {
      $result['msg'] = '上传图片大小超出指定大小';
      return $result;
    }
    // 保存图片
    // 设置图片名称
    $filename = date('YmdHis', time()) . mt_rand(1000, 9999) . mt_rand(1000, 9999) . '.' . $ext;
    // 判断图片是否 http post 上传
    if (is_uploaded_file($file['tmp_name']) === true) {
      $res = move_uploaded_file($file['tmp_name'], $path . '/' . $filename);

      if ($res === true) {
        $result = [
          'code' => 1,
          'msg' => '上传成功',
          'data' => '/uploads/' . $date . '/' . $filename
        ];
      } else {
        $result['msg'] = '上传失败';
      }
    } else {
      $result['msg'] = '上传错误';
    }
    return $result;
  }
}

// 检查用户是否已经登录
if (!function_exists('AuthCheck')) {
  /**
   * @param bool $redirect 重定向,方便操作
   * @return array|bool
   */
  function AuthCheck($redirect = true)
  {
    // 从cookie里获取登录信息
    $auth = isset($_COOKIE['auth']) ? json_decode($_COOKIE['auth'], true) : [];
    // 如果登录页面为空就跳转至登录页
    if (empty($auth)) {
      if ($redirect === true) {
        notice('请先登录', 'login.php');
      }
      return false;
    }
    // 获取id和用户名再验证登录信息是否正确
    $id = $auth['id'] ?? 0;
    $username = $auth['username'] ?? '';
    $sql = "SELECT * FROM `pre_admin` WHERE `id`= '$id' AND `username` = '$username'";
    $res = find($sql);
    if ($res) {
      // 更新cookie
      $data = [
        'id' => $res['id'],
        'username' => $res['username'],
        'avatar' => $res['avatar']   // 用来更新头像信息
      ];
      // 存储登录信息
      setcookie('auth', json_encode($data));
      return $data;   // 返回登录信息
    } else {
      // 删除非法cookie
      setcookie('auth', '', time() - 1);
      if ($redirect === true) {
        notice('非法登录', 'login.php');
      }
      return false;
    }
  }
}

if (!function_exists('GetUrl')) {
  /**
   * 获取重组后地址
   */
  function GetUrl()
  {
    $url = $_SERVER['PHP_SELF'] . '?';

    if ($_GET) {
      foreach ($_GET as $key => $val) {
        if ($key !== 'page') {
          // 处理地址栏中?后面的属性，如果不是page属性将其拼接上去
          $url .= $key . '=' . $val . '&';
        }
      }
    }
    return $url; // 返回的该url用以拼接page，作用于分页
  }
}


if (!function_exists('ShowPage')) {
  /**
   * 分页器函数
   * @param int|string $current 当前页
   * @param int|string $count 数据总条数
   * @param int|string $limit 每页显示多少条数据
   * @param int|string $size 页码
   * @param string $class 样式类名
   */
  function ShowPage($current, $count, $limit, $size = 5, $class = 'digg')
  {
    $page = ''; // 用来拼接html结构
    // 当数据总条数大于每页显示的数据才会显示分页
    if ($count > $limit) {
      // 总分页
      $PageCount = ceil($count / $limit);
      // 调用函数，获取当前的工作目录
      $url = GetUrl();
      $page .= '<div class="' . $class . '">'; // 插入样式

      // 首页&上一页
      if ($current == 1) {
        $page .= '<span class="disabled">首&nbsp;页</span>';
        $page .= '<span class="disabled">上一页</span>';
      } else {
        // $url PersonList.php?name=demo&page=1
        $page .= '<a href="' . $url . 'page=1">首&nbsp;页</a>';
        $page .= '<a href="' . $url . 'page=' . ($current - 1) . '">上一页</a>';
      }

      // 处理页码
      if ($current <= floor($size / 2)) {
        $start = 1;
        $end = $PageCount < $size ? $PageCount : $size;
      } elseif ($current >= $PageCount - floor($size / 2)) {
        $start = $PageCount - $size + 1 <= 0 ? 1 : $PageCount - $size + 1;
        $end = $PageCount;
      } else {
        // 当前页刚好在中间位置
        $start = $current - floor($size / 2);
        $end = $current + floor($size / 2);
      }

      // 显示页码
      for ($i = $start; $i <= $end; $i++) {
        if ($i == $current) {
          $page .= '<span class="current">' . $i . '</span>';
        } else {
          $page .= '<a href="' . $url . 'page=' . $i . '">' . $i . '</a>';
        }
      }

      // 下一页 尾页
      if ($PageCount == $current) {
        $page .= '<span class="disabled">下一页</span>';
        $page .= '<span class="disabled">尾&nbsp;页</span>';
      } else {
        $page .= '<a href="' . $url . 'page=' . ($current + 1) . '">下一页</a>';
        $page .= '<a href="' . $url . 'page=' . $PageCount . '">尾&nbsp;页</a>';
      }

      $page .= '</div>'; // div结尾
    }

    return $page;
  }
}
